package com.zhangfb95.crosschain.server.controller;

import com.zhangfb95.crosschain.infra.exception.BusinessException;
import com.zhangfb95.crosschain.infra.model.Result;
import com.zhangfb95.crosschain.server.infra.model.controller.request.rpcchain.RpcExecuteReq;
import com.zhangfb95.crosschain.server.infra.model.controller.response.rpcchain.RpcExecuteRes;
import com.zhangfb95.crosschain.server.infra.model.mapper.entity.ChainScript;
import com.zhangfb95.crosschain.server.infra.util.GroovyObjectUtil;
import com.zhangfb95.crosschain.server.service.ChainScriptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author zhangfubing
 * @since 2023/12/4
 */
@RequestMapping("/rpc/chain-script")
@RestController
public class RpcChainScriptController {

    @Autowired
    private ChainScriptService chainScriptService;

    @PostMapping("/execute")
    public Result<RpcExecuteRes> execute(@RequestBody @Validated RpcExecuteReq req) {
        // 查询链脚本
        Long scriptId = req.getScriptId();
        ChainScript chainScript = chainScriptService.getById(scriptId);
        if (chainScript == null) {
            throw new BusinessException("chainScript not find, id=" + scriptId);
        }

        // 执行链脚本
        String scriptText = chainScript.getScriptText();
        Object scriptReturnValue = GroovyObjectUtil.invokeMethod(scriptText, req.getFunctionName(), req.getArgs());
        return Result.ok(new RpcExecuteRes().setScriptReturnValue(scriptReturnValue));
    }
}
